package com.gzzyy.unionchain.data

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder
import android.util.Log
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject
import com.gzzyy.unionchain.LiveEvent
import com.gzzyy.unionchain.communicate.bean.PageInfo
import com.gzzyy.unionchain.data.bean.BlockJ
import com.gzzyy.unionchain.data.bean.TransactionRecord
import com.gzzyy.unionchain.data.bean.TransferBeanJ
import com.jeremyliao.liveeventbus.LiveEventBus

class SaveDataService : Service() {

    companion object {
        const val SaveList = 1
        const val SaveSingle = 2
        const val CacheSingle = 3
        const val SaveSingleByHash = 4

        const val SaveSingleBlock = 5
        const val SaveBlockList = 6

        private val transferMap = hashMapOf<String, JSONObject>()

        @Volatile
        private var getListEnd = true
    }

    override fun onCreate() {
        super.onCreate()
        LiveEventBus.get(LiveEvent.SaveData, Pair::class.java).observeForever {
            val flag = it.first as Int
            val content = it.second as String
            when (flag) {
                SaveSingle -> {
                    val jsonObj = JSON.parseObject(content)
                    doSingleSave(jsonObj)
                }
                SaveList -> {
                    val dataObj = JSON.parseObject(content)
                    val transferJsonBeanList =
                        dataObj.getJSONArray("list").toJavaList(TransferBeanJ::class.java)
                    val transferBeanList = List(transferJsonBeanList.size) { index ->
                        transferJsonBeanList[index].turnToTransactionRecord()
                    }
                    doListSave(transferBeanList)
                    val pageInfo = dataObj.getJSONObject("page_info")
                        .toJavaObject(PageInfo::class.java)
                    getListEnd = !pageInfo.hasNextPage()
                    Log.e("test", "$pageInfo")
                    Log.e("test", "getListEnd = $getListEnd")
                    if (getListEnd) {
                        LiveEventBus.get(LiveEvent.GetTransferListEnd).post(Any())
                    } else {
                        LiveEventBus.get(LiveEvent.RequestTransferList)
                            .post(Pair(pageInfo.page++, pageInfo.page_size))
                    }
                }
                CacheSingle -> {
                    Log.e("test", "CacheSingle $content")
                    val jsonObj = JSON.parseObject(content)
                    val hash = jsonObj.getJSONObject("data").getString("hash")
                    Log.e("test", "CacheSingle hash = $hash")
                    transferMap.put(hash, jsonObj)
                }
                SaveSingleByHash -> {
                    Log.e("test", "SaveSingleByHash hash = $content")
                    doSaveByHash(content)
                }
                SaveSingleBlock -> {
                    Log.e("test", "SaveSingleBlock  json = $content")
                    val block = JSON.parseObject(content, BlockJ::class.java).turnToBlock()
                    val blockBox = ObjectBox.getBlockBox()
                    blockBox.put(block)
                }
                SaveBlockList -> {
                    Log.e("test", "SaveBlockList  json = $content")
                    val blockJList = JSON.parseArray(content, BlockJ::class.java)
                    val blockList =
                        List(blockJList.size) { index -> blockJList[index].turnToBlock() }
                    val blockBox = ObjectBox.getBlockBox()
                    blockBox.put(blockList)
                }
            }
        }
    }

    private fun doSaveByHash(hash: String?) {
        val jsonObject = transferMap.get(hash)
        Log.e("test", "doSaveByHash jsonObject = ${jsonObject?.toJSONString()}")
        doSingleSave(jsonObject)
    }

    private fun doSingleSave(jsonObj: JSONObject?) {
        if (jsonObj != null) {
            Log.e("test", "doSingleSave ${jsonObj.toJSONString()}")
            val dataJsonObj = jsonObj.getJSONObject("data")
            val record = TransactionRecord(
                dataJsonObj.getString("from"),
                dataJsonObj.getString("to"),
                dataJsonObj.getFloat("money"),
                dataJsonObj.getString("hash"),
                dataJsonObj.getFloat("from_utxo"),
                dataJsonObj.getFloat("to_utxo"),
                dataJsonObj.getString("hash_sign"),
                dataJsonObj.getString("nonce"),
                dataJsonObj.getString("prevhash"),
                dataJsonObj.getIntValue("height"),
                dataJsonObj.getLongValue("create_time")
            )
            val recordBox = ObjectBox.boxStore.boxFor(TransactionRecord::class.java)
            Log.e("test", "before count = ${recordBox.count()}")
            recordBox.put(record)
            Log.e("test", "after count = ${recordBox.count()}")
            LiveEventBus.get(LiveEvent.SaveSingleEnd).post(Any())
        }
    }

    private fun doListSave(recordList: List<TransactionRecord>) {
        val recordBox = ObjectBox.boxStore.boxFor(TransactionRecord::class.java)
        recordBox.put(recordList)
    }


    private val localBinder = LocalBinder()
    override fun onBind(intent: Intent): IBinder {
        return localBinder
    }

    inner class LocalBinder : Binder() {
        fun getService(): SaveDataService {
            return this@SaveDataService
        }
    }
}
